package com.sephiron.clocksynchronizer;

import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.BitmapDrawable;
import android.media.ExifInterface;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.text.Editable;
import android.text.InputFilter;
import android.text.TextWatcher;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.DatePicker;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.NumberPicker;
import android.widget.TimePicker;
import android.widget.Toast;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;

import uk.co.senab.photoview.PhotoViewAttacher;

public class SetDateNTimeWithPictureFragment extends Fragment {
	public static final String EXTRA_CCTV_CALENDAR = "com.sephiron.clocksynchronizer.cctv.calendar";
	public static final String EXTRA_REAL_CALENDAR = "com.sephiron.clocksynchronizer.real.calendar";
    private static final String EXTRA_IMAGE_PATH = "com.sephiron.clocksynchronizer.image.uri";
    private static final String TAG = "com.sephiron.clocksynchronizer.image.SetDateNTimeWithPictureFragment";
    public static final String EXTRA_PICTURE_PATH = "com.sephiron.clocksynchronizer.image.path";

    private static Calendar mPickerCalendar;
    private static Calendar mTakenCalendar;

	private static ImageView mPictureView;
    private static String mPicturePath;
    private static PhotoViewAttacher mAttacher;

	private static DatePicker mDatePicker;

	private static TimePicker mTimePicker;
	private static NumberPicker mSecondPicker;
	private static EditText mSecondTextField;
	private static Button mPlus1Sec;
	private static Button mMinus1Sec;

	private static Button mCancel;
    private static Button mRotate;
	private static Button mOk;
	private static Button mChangePicker;

	private static LinearLayout mDatePickerVG;
	private static LinearLayout mTimePickerVG;
    private static Bitmap selectedImage;
    private static BitmapFactory.Options options;

    @Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		getActivity().setTitle(R.string.setCctvTimeNDateWithPicture);

        mPickerCalendar = (Calendar) getArguments().getSerializable(EXTRA_CCTV_CALENDAR);
        mPicturePath = getArguments().getString(EXTRA_IMAGE_PATH);


        //set exif
        try {
            ExifInterface exif = new ExifInterface(mPicturePath);
            String dateTime = exif.getAttribute(ExifInterface.TAG_DATETIME);
            if (dateTime == null) {
                throw new ParseException("R.string.error_on_parsing_exif", Thread.currentThread().getStackTrace()[2].getLineNumber());
            }
            mTakenCalendar = parseExifDatetime(dateTime);
        } catch (IOException e) {
            Toast.makeText(getActivity(), R.string.error_on_loading_image, Toast.LENGTH_SHORT).show();
            e.printStackTrace();
        } catch (ParseException e) {
            Toast.makeText(getActivity(), R.string.error_on_parsing_exif, Toast.LENGTH_SHORT).show();
            e.printStackTrace();
        }
    }

    //get image exif, parse and return
    private Calendar parseExifDatetime(String dateTime) throws ParseException {
        Calendar parsed = Calendar.getInstance();
        SimpleDateFormat sFormatter = new SimpleDateFormat("yyyy:MM:dd HH:mm:ss");

        try {
            parsed.setTime(sFormatter.parse(dateTime));
        } catch (IllegalArgumentException ex) {
            Toast.makeText(getActivity(), R.string.error_on_loading_image, Toast.LENGTH_SHORT).show();
            ex.printStackTrace();
        }
        return parsed;
    }

    public View onCreateView(LayoutInflater inflater, ViewGroup parent,
							 Bundle savedInstanceState) {
		View v = inflater.inflate(R.layout.fragment_set_cctv_date_n_time_with_picture, parent, false);

		mPictureView = (ImageView) v.findViewById(R.id.fragment_set_cctv_date_n_time_with_picture_image);
		//TODO: 이미지 초기 셋팅
        //validate image Uri and set image view
        //set image view
        try {
            final InputStream imageStream = new FileInputStream(mPicturePath);
            options = new BitmapFactory.Options();
            options.inPreferredConfig = Bitmap.Config.RGB_565;
            selectedImage = BitmapFactory.decodeStream(imageStream, null, options);
//            final Bitmap selectedImage = BitmapFactory.decodeFile(mPicturePath, options);
            mPictureView.setImageBitmap(selectedImage);
            //make pinch to zoom
            mAttacher = new PhotoViewAttacher(mPictureView);
            mAttacher.setScaleType(ImageView.ScaleType.CENTER_CROP);
        } catch (FileNotFoundException e) {
            getActivity().setResult(Activity.RESULT_CANCELED);
            getActivity().finish();
            Toast.makeText(getActivity(), R.string.error_on_loading_image, Toast.LENGTH_SHORT).show();
            e.printStackTrace();
        }


        mDatePicker = (DatePicker) v.findViewById(R.id.fragment_set_cctv_date_with_picture_date_picker);
		{
			int year = mPickerCalendar.get(Calendar.YEAR);
			int month = mPickerCalendar.get(Calendar.MONTH);
			int day = mPickerCalendar.get(Calendar.DAY_OF_MONTH);
			mDatePicker.init(year, month, day, new DatePicker.OnDateChangedListener() {

				@Override
				public void onDateChanged(DatePicker view, int year,
										  int monthOfYear, int dayOfMonth) {
					mPickerCalendar.set(year, monthOfYear, dayOfMonth);
					getArguments().putSerializable(EXTRA_CCTV_CALENDAR, mPickerCalendar);
				}
			});
		}

		mTimePicker = (TimePicker) v.findViewById(R.id.fragment_set_cctv_date_n_time_with_picture_time_picker);
		mTimePicker.setIs24HourView(true);
		mTimePicker.setOnTimeChangedListener(new TimePicker.OnTimeChangedListener() {
			@Override
			public void onTimeChanged(TimePicker view, int hour, int minute) {
				mPickerCalendar.set(Calendar.HOUR_OF_DAY, hour);
				mPickerCalendar.set(Calendar.MINUTE, minute);
				getArguments().putSerializable(EXTRA_CCTV_CALENDAR, mPickerCalendar);
			}
		});

		if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) {
			mSecondTextField = (EditText) v.findViewById(R.id.fragment_set_cctv_date_n_time_with_picture_secTV);
			mSecondTextField.addTextChangedListener(new TextWatcher() {
				@Override
				public void onTextChanged(CharSequence c, int start,
										  int before, int count) {
					if (c.length() != 0) {
						mPickerCalendar.set(Calendar.SECOND,
								Integer.parseInt(c.toString()));
					}
				}

				public void beforeTextChanged(CharSequence c, int start,
											  int count, int after) {
					// this space intentionally left blank
				}

				public void afterTextChanged(Editable c) {
					// this one too
				}
			});

			mSecondTextField
					.setFilters(new InputFilter[]{new InputFilterMinMax("0",
                            "59")});

			mPlus1Sec = (Button) v.findViewById(R.id.fragment_set_cctv_date_n_time_with_picture_plus1sec);
			mPlus1Sec.setOnClickListener(new View.OnClickListener() {
				@Override
				public void onClick(View v) {
					int t = Integer.parseInt(mSecondTextField.getText()
							.toString());
					if (t == 59) {
						mSecondTextField.setText("0");
					} else {
						mSecondTextField.setText(String.valueOf(++t));
					}
				}
			});

			mMinus1Sec = (Button) v.findViewById(R.id.fragment_set_cctv_date_n_time_with_picture_minus1sec);
			mMinus1Sec.setOnClickListener(new View.OnClickListener() {
				@Override
				public void onClick(View v) {
					int t = Integer.parseInt(mSecondTextField.getText()
							.toString());
					if (t == 0) {
						mSecondTextField.setText("59");
					} else {
						mSecondTextField.setText(String.valueOf(--t));
					}
				}
			});

		} else {
			mSecondPicker = (NumberPicker) v.findViewById(R.id.fragment_set_cctv_date_n_time_with_picture_second_picker);
			mSecondPicker.setMaxValue(59);
			mSecondPicker.setMinValue(0);
			mSecondPicker.setOnValueChangedListener(new NumberPicker.OnValueChangeListener() {

				@Override
				public void onValueChange(NumberPicker picker, int oldVal,
										  int newVal) {
					mPickerCalendar.set(Calendar.SECOND, newVal);
					getArguments().putSerializable(EXTRA_CCTV_CALENDAR, mPickerCalendar);
				}
			});
		}

		mCancel = (Button) v.findViewById(R.id.fragment_set_cctv_date_n_time_with_picture_cancel);
        mCancel.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                getActivity().setResult(Activity.RESULT_CANCELED);
                getActivity().finish();
            }
        });


		mOk = (Button) v.findViewById(R.id.fragment_set_cctv_date_n_time_with_picture_ok);
		mOk.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent i = new Intent();
                i.putExtra(EXTRA_CCTV_CALENDAR, mPickerCalendar);
                i.putExtra(EXTRA_REAL_CALENDAR, mTakenCalendar);
                getActivity().setResult(Activity.RESULT_OK, i);
                getActivity().finish();
            }
        });

		mChangePicker = (Button) v.findViewById(R.id.fragment_set_cctv_date_n_time_with_picture_change_picker);
		mChangePicker.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {
				if(mDatePickerVG.getVisibility() == View.VISIBLE) {
					mDatePickerVG.setVisibility(View.INVISIBLE);
					mTimePickerVG.setVisibility(View.VISIBLE);
                    mChangePicker.setText(R.string.fragment_set_cctv_date_n_time_with_picture_to_date);
				}  else {
					mDatePickerVG.setVisibility(View.VISIBLE);
					mTimePickerVG.setVisibility(View.INVISIBLE);
                    mChangePicker.setText(R.string.fragment_set_cctv_date_n_time_with_picture_to_time);
				}
			}
		});

        mRotate = (Button) v.findViewById(R.id.fragment_set_cctv_date_n_time_with_picture_rotate);
        mRotate.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mAttacher.setRotationBy(90);
            }
        });

		mDatePickerVG = (LinearLayout) v.findViewById(R.id.fragment_set_cctv_date_with_picture_linear_layout_of_date_picker);
		mTimePickerVG = (LinearLayout) v.findViewById(R.id.fragment_set_cctv_date_with_picture_linear_layout_of_time_picker);

        updateTimePickers();
		return v;
	}

	protected void updateTimePickers() {
		mTimePicker.setCurrentHour(mPickerCalendar.get(Calendar.HOUR_OF_DAY));
		mTimePicker.setCurrentMinute(mPickerCalendar.get(Calendar.MINUTE));
		if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) {
			mSecondTextField.setText(String.valueOf(mPickerCalendar
					.get(Calendar.SECOND)));
		} else {
			mSecondPicker.setValue(mPickerCalendar.get(Calendar.SECOND));
		}
	}

    public static SetDateNTimeWithPictureFragment newInstance(Calendar calendar, String imagePath) {
        Bundle args = new Bundle();
        // real calendar is not needed in this fragment, so only cctv calendar is put into args
        args.putSerializable(EXTRA_CCTV_CALENDAR, calendar);
        args.putString(EXTRA_IMAGE_PATH, imagePath);

        SetDateNTimeWithPictureFragment fragment = new SetDateNTimeWithPictureFragment();
        fragment.setArguments(args);

        return fragment;
    }

    @Override
    public void onDestroy() {
        selectedImage.recycle();
        selectedImage = null;
        super.onDestroy();
    }
}